using System;
using System.Windows.Input;

namespace WebServiceTool.Utilities
{
    /// <summary>
    /// 通用的ICommand实现，用于处理UI命令
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region 字段
        private readonly Action _execute;
        private readonly Func<bool> _canExecute;
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="execute">要执行的操作</param>
        /// <param name="canExecute">判断是否可以执行的函数</param>
        public RelayCommand(Action execute, Func<bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute ?? (() => true);
        }
        #endregion

        #region ICommand实现
        /// <summary>
        /// 判断命令是否可以执行的事件
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 判断命令是否可以执行
        /// </summary>
        /// <param name="parameter">命令参数</param>
        /// <returns>是否可以执行</returns>
        public bool CanExecute(object parameter)
        {
            return _canExecute();
        }

        /// <summary>
        /// 执行命令
        /// </summary>
        /// <param name="parameter">命令参数</param>
        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                _execute();
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 触发CanExecuteChanged事件
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }
        #endregion
    }

    /// <summary>
    /// 带参数的通用ICommand实现
    /// </summary>
    /// <typeparam name="T">参数类型</typeparam>
    public class RelayCommand<T> : ICommand
    {
        #region 字段
        private readonly Action<T> _execute;
        private readonly Func<T, bool> _canExecute;
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="execute">要执行的操作</param>
        /// <param name="canExecute">判断是否可以执行的函数</param>
        public RelayCommand(Action<T> execute, Func<T, bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute ?? (parameter => true);
        }
        #endregion

        #region ICommand实现
        /// <summary>
        /// 判断命令是否可以执行的事件
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 判断命令是否可以执行
        /// </summary>
        /// <param name="parameter">命令参数</param>
        /// <returns>是否可以执行</returns>
        public bool CanExecute(object parameter)
        {
            return _canExecute((T)parameter);
        }

        /// <summary>
        /// 执行命令
        /// </summary>
        /// <param name="parameter">命令参数</param>
        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                _execute((T)parameter);
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 触发CanExecuteChanged事件
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }
        #endregion
    }
}